﻿using CommonEntity.CommonImageEntities;
using ImageDomain.DE;
using ImageDomain.Utils;
using itk.simple;
using OpenCvSharp;
using System.Threading.Tasks;
using static System.Net.Mime.MediaTypeNames;
using Point3d = CommonEntity.CommonImageEntities.Point3d;

namespace ImageDomain.Agg;
public class ArmBoneSegAgg : IArmBoneSegAgg
{
    public Dictionary<SegToolsEnum, IList<Point3d>> SegMarks { get; internal set; }

    /// <summary>
    /// 由此一 label 三
    /// </summary>
    public IMaskImage3d? LablesImage3d { get; set; }
    public IMaskImage3d UlnaImage3d { get; internal set; }
    public IMaskImage3d RadiusImage3d { get; internal set; }
    public IMaskImage3d TfccImage3d { get;  internal set; }
    public IImage3d CtImage { get; internal set; }

    public async Task<bool> LoadLabelsImage(string file)
    {
        if (!File.Exists(file))
        {
            var maskItkImage = ImageHandler.Instance.CreateMaskImage(CtImage);
            LablesImage3d = new MaskImage3d(maskItkImage);
            return true;
        }
        else
        {
            var itkImage = await ReadUtil.Instance.ReadImageAsync(file, true);
            LablesImage3d = new MaskImage3d(itkImage);
        }
        
        return true;
    }

    /// <summary>
    /// mha mhd nii.gz
    /// </summary>
    /// <param name="file"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public async Task LoadOriginImage(string file)
    {
         CtImage = new Image3d();
         await CtImage.SetImage(file);
    }

    /// <summary>
    /// load dcms
    /// </summary>
    /// <param name="dir"></param>
    /// <returns></returns>
    public async Task LoadOriginImageByDir(string dir)
    {
        CtImage = new Image3d();
        var files = DcmHelper.GetAllDicomFiles(dir);
        await CtImage.SetImage(files);
    }

    public async Task SetSegMaskImage(byte[][][] image_array)
    {
        await Task.Run(() =>
        {
            var itkImage = image_array.ConvertBytesToImage(CtImage.OriginSize!);

            itkImage.SetSpacing(new VectorDouble() { CtImage.Spacing![0], CtImage.Spacing![1], CtImage.Spacing![2] });
            itkImage.SetOrigin(new VectorDouble() { CtImage.Origin![0], CtImage.Origin![1], CtImage.Origin![2] });
            itkImage.SetDirection(new VectorDouble()
            {
                CtImage.Direction![0], CtImage.Direction![1], CtImage.Direction![2],
                CtImage.Direction![3], CtImage.Direction![4], CtImage.Direction![5],
                CtImage.Direction![6], CtImage.Direction![7], CtImage.Direction![8],
            });

            LablesImage3d = new MaskImage3d(itkImage);

            //UlnaImage3d = new MaskImage3d(LabelSplitUtil.ExtractLabel(itkImage, (int)SegToolsEnum.MarkULNA));
            //RadiusImage3d = new MaskImage3d(LabelSplitUtil.ExtractLabel(itkImage, (int)SegToolsEnum.MarkRADIUS));
            //TfccImage3d = new MaskImage3d(LabelSplitUtil.ExtractLabel(itkImage, (int)SegToolsEnum.MarkTFCC));
        });
    }

    /// <summary>
    /// load dcms
    /// </summary>
    /// <param name="dcms"></param>
    /// <returns></returns>
    public async Task LoadOriginImage(IList<string> dcms)
    {
        CtImage = new Image3d();
        await CtImage.SetImage(dcms);

        var maskItk = ImageHandler.Instance.CreateMaskImage(CtImage);
        LablesImage3d = new MaskImage3d(maskItk);
    }

    /// <summary>
    /// 根据横断面的勾画数据 构建mask3d
    /// </summary>
    /// <param name="matDic"></param>
    /// <returns></returns>
    public async Task BuildMaskByAxMat(Dictionary<int, Mat> matDic)
    {
        foreach (var index in matDic.Keys)
        {
            for (var i = 0; i < matDic[index].Height; i++)
            {
                for(var j =0; j< matDic[index].Width; j++)
                {
                    var val = matDic[index].At<byte>(i, j);

                    switch (val)
                    {
                        case 0:
                            LablesImage3d!.ItkImage!.SetPixelAsInt8(new VectorUInt32() { (uint)j, (uint)i, (uint)index }, 0);
                            break;
                        case 126:
                            LablesImage3d!.ItkImage!.SetPixelAsInt8(new VectorUInt32() { (uint)j, (uint)i, (uint)index }, 1);
                            break;
                        case 226:
                            LablesImage3d!.ItkImage!.SetPixelAsInt8(new VectorUInt32() { (uint)j, (uint)i, (uint)index }, 2);
                            break;
                        case 199:
                            LablesImage3d!.ItkImage!.SetPixelAsInt8(new VectorUInt32() { (uint)j, (uint)i, (uint)index }, 3);
                            break;
                    }
                }
            }
        }
    }

    public async Task BuildMaskBySagMat(Dictionary<int, Mat> matDic)
    {
        foreach (var index in matDic.Keys)
        {
            for (var i = 0; i < matDic[index].Height; i++)
            {
                for (var j = 0; j < matDic[index].Width; j++)
                {
                    var val = matDic[index].At<byte>(i, j);

                    switch (val)
                    {
                        case 0: break;
                        case 126:
                            LablesImage3d!.ItkImage!.SetPixelAsInt8(new VectorUInt32() { (uint)index, (uint)j, (uint)i }, 1);
                            break;
                        case 226:
                            LablesImage3d!.ItkImage!.SetPixelAsInt8(new VectorUInt32() { (uint)index, (uint)j, (uint)i }, 2);
                            break;
                        case 199:
                            LablesImage3d!.ItkImage!.SetPixelAsInt8(new VectorUInt32() { (uint)index, (uint)j, (uint)i }, 3);
                            break;
                    }
                }
            }
        }
    }

    public async Task BuildMaskByCorMat(Dictionary<int, Mat> matDic)
    {
        foreach (var index in matDic.Keys)
        {
            for (var i = 0; i < matDic[index].Height; i++)
            {
                for (var j = 0; j < matDic[index].Width; j++)
                {
                    var val = matDic[index].At<byte>(i, j);

                    switch (val)
                    {
                        case 0: break;
                        case 126:
                            LablesImage3d!.ItkImage!.SetPixelAsInt8(new VectorUInt32() { (uint)j, (uint)index, (uint)i }, 1);
                            break;
                        case 226:
                            LablesImage3d!.ItkImage!.SetPixelAsInt8(new VectorUInt32() { (uint)j, (uint)index, (uint)i }, 2);
                            break;
                        case 199:
                            LablesImage3d!.ItkImage!.SetPixelAsInt8(new VectorUInt32() { (uint)j, (uint)index, (uint)i }, 3);
                            break;
                    }
                }
            }
        }
    }


    public async Task SaveDataToHistory()
    {
        var folder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"HistoryImageFolder", CtImage.SeriesDescription);
        if (!Directory.Exists(folder))
        {
            Directory.CreateDirectory(folder);
        }

        await WriteUtil.Instance.WriteToDiskAsync(CtImage.ItkImage!,
            Path.Combine(folder, $"{CtImage.SeriesDescription}.nii.gz"));

        await WriteUtil.Instance.WriteToDiskAsync(LablesImage3d!.ItkImage!,
            Path.Combine(folder, $"{CtImage.SeriesDescription}_mask.nii.gz"));
    }

    // todo 使用 fo-dicom 判断是否是dicom图像, 并整理一个加载病人 studuid seriesdescription 的 方法

}
